home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / oasis / oasis1-1.lha / oasis-1.1 / par.y < prev    next >
Text File  |  1992-05-01  |  46KB  |  834 lines

  1. /*==========================================================================*
  2.     Oasis Alpha Version 1.1               (C) Copyright 1992 Fah-Chun Cheong
  3.     Revised: 5/1/92 by: fcc@eecs.umich.edu    and The University of Michigan
  4.     ------------------------------------------------------------------------
  5.     Permission to use, copy, modify, distribute, sell and resell Oasis Alpha
  6.     software and its documentation for any purpose and without fee is hereby
  7.     granted, provided that the authorship be appropriately credited and
  8.     acknowledged, and that the above copyright notice appear in all copies
  9.     and both the copyright notice and this permission notice appear in
  10.     supporting documentation. The author makes no representations about the
  11.     suitability of this software for any purpose. It is provided "as is"
  12.     without express or implied warranty. Oasis Alpha is free, caveat emptor!
  13.     ------------------------------------------------------------------------
  14.     To request Oasis Alpha source code:   oasis-alpha-request@eecs.umich.edu
  15.     To enroll in the mailing list:        oasis-alpha-request@eecs.umich.edu
  16.     To send bug reports:                  oasis-alpha-bugs@eecs.umich.edu
  17.     To discuss openly all matters Oasis:  oasis-alpha@eecs.umich.edu
  18.  *==========================================================================*/
  19. %{
  20. #include                "parser.h"
  21.  
  22. Type                   *Top;
  23. Type                   *Bot;
  24. Type                   *Int;
  25. Type                   *Real;
  26. Type                   *Char;
  27. Type                   *Condv;
  28. Node                   *Izero;
  29. Node                   *Rzero;
  30. Node                   *Blank;
  31. Node                   *Nil;
  32. Node                   *Anon;
  33. Node                   *Self;
  34. Node                   *Site;
  35.  
  36. Spec                   *specs;
  37. Imp                    *imps;
  38. Goal                   *goal;
  39. Att                    *Atts0;
  40.  
  41. static  int            *_;
  42. static  int             level;
  43. static  int             kind;
  44. static  int             prot;
  45. static  int             step;
  46. static  int             flow;
  47. static  int             goff;
  48. static  int             coff;
  49. static  int             aoff;
  50. static  int             moff;
  51. static  int             size;
  52.  
  53. static  Spec           *base;
  54. static  Gene           *genes, *gs;
  55. static  Cond           *conds;
  56. static  Cst            *csts;
  57. static  Att            *atts0, *atts, *as;
  58. static  Met            *mets,  *ms;
  59. static  Arg            *args0, *args;
  60. static  Rule           *rules;
  61. static  Pred           *last;
  62. static  Dim            *dims;
  63. static  Var            *vars;
  64. static  Node           *self;
  65. static  Type           *type,  *t;
  66. %}
  67. %union {
  68.         int     i;
  69.         double  f;
  70.         char    c;
  71.         char   *s;
  72.         Spec   *spec;
  73.         Gene   *gene;
  74.         Cond   *cond;
  75.         Att    *att;
  76.         Met    *met;
  77.         Arg    *arg;
  78.         Type   *type;
  79.         Con    *con;
  80.         Dim    *dim;
  81.         Imp    *imp;
  82.         Rule   *rule;
  83.         Head   *head;
  84.         Clu    *clu;
  85.         Pred   *pred;
  86.         Var    *var;
  87.         Par    *par;
  88.         Prop   *prop;
  89.         Node   *node;
  90.         struct {
  91.           Dim  *dims;
  92.           int   size;
  93.           Prop *props;
  94.           Node *node;
  95.           Type *type;
  96.         }       ary;
  97.         struct {
  98.           Dim  *dims;
  99.           Type *type;
  100.         }       idx;
  101.         struct {
  102.           Type *t;
  103.           int   size;
  104.           Att  *atts;
  105.           Type *type;
  106.         }       inst;
  107.         struct {
  108.           Node *node;
  109.           int   cost;
  110.         }       exp;
  111. }
  112. %token          CLASS CONSTANT ATTRIBUTE METHOD
  113. %token          PUBLIC PROTECTED PRIVATE
  114. %token          INT REAL CHAR
  115. %token          SELF NIL
  116. %token          DOT DO ISA IF THEN
  117. %token          EQ NE GT GE LT LE
  118. %token  <s>     ID CID SID
  119. %token  <s>     ATINET
  120. %token  <i>     INTEGER
  121. %token  <f>     FLOAT
  122. %token  <s>     CHARACTER
  123. %token  <s>     STRING
  124. %type   <clu>   goal
  125. %type   <s>     header
  126. %type   <s>     cid
  127. %type   <s>     id
  128. %type   <gene>  genes
  129. %type   <gene>  gene
  130. %type   <s>     attid
  131. %type   <arg>   arguments
  132. %type   <arg>   argument
  133. %type   <arg>   args
  134. %type   <arg>   arg
  135. %type   <s>     argid
  136. %type   <con>   types0
  137. %type   <con>   types
  138. %type   <type>  type
  139. %type   <dim>   dimensions
  140. %type   <i>     dimension
  141.  
  142. %type   <s>     identifier
  143. %type   <rule>  rules
  144. %type   <rule>  rule
  145. %type   <rule>  clause
  146. %type   <head>  head
  147. %type   <clu>   body
  148. %type   <pred>  cluster
  149. %type   <pred>  messages
  150. %type   <pred>  message
  151. %type   <pred>  predicate
  152. %type   <node>  destination
  153. %type   <pred>  primitive
  154. %type   <pred>  matching
  155. %type   <pred>  comparison
  156. %type   <node>  rhs
  157. %type   <node>  lhs
  158. %type   <i>     relop
  159.  
  160. %type   <par>   parameters0
  161. %type   <par>   parameters
  162. %type   <par>   parameter
  163. %type   <node>  value
  164. %type   <node>  pvalue
  165. %type   <node>  lvalue
  166. %type   <node>  gvalue
  167. %type   <node>  rvalue
  168. %type   <node>  instance
  169. %type   <node>  list
  170. %type   <node>  null
  171. %type   <type>  l2
  172. %type   <prop>  elements
  173. %type   <node>  element
  174. %type   <node>  array
  175. %type   <node>  string
  176. %type   <idx>   l3
  177. %type   <ary>   sizes_l3
  178. %type   <ary>   sizes
  179. %type   <ary>   size
  180. %type   <ary>   l5
  181. %type   <node>  items0
  182. %type   <node>  items
  183. %type   <node>  item
  184. %type   <node>  component
  185. %type   <ary>   l6
  186. %type   <node>  handle
  187. %type   <node>  atsite0
  188. %type   <node>  atsite
  189. %type   <node>  agent
  190. %type   <node>  object
  191. %type   <inst>  l1
  192. %type   <prop>  properties0
  193. %type   <prop>  properties
  194. %type   <prop>  property
  195. %type   <node>  global
  196. %type   <node>  local
  197. %type   <node>  varid
  198. %type   <node>  refid
  199. %type   <node>  accessors
  200. %type   <node>  accessor
  201. %type   <dim>   l0
  202. %type   <prop>  indices
  203. %type   <node>  index
  204.  
  205. %type   <node>  expression
  206. %type   <node>  expression2
  207. %type   <exp>   expr
  208. %type   <exp>   term
  209. %type   <exp>   factor
  210. %type   <exp>   expr2
  211. %type   <exp>   term2
  212. %type   <exp>   factor2
  213. %type   <exp>   expr1
  214. %type   <exp>   term1
  215. %type   <exp>   factor1
  216. %type   <i>     addop
  217. %type   <i>     mulop
  218. %type   <node>  literal
  219. %type   <node>  self
  220. %type   <node>  nil
  221. %%
  222. start           :                                       { lineno = 1;
  223.                                                           fname  = NUL;
  224.                                                           kind   = AGENT;
  225.                                                           self   = Self;
  226.                                                           level  = 0;
  227.                                                           conds  = NUL;
  228.                                                           csts   = NUL;
  229.                                                           mets   = NUL;
  230.                                                           atts0  = Atts0; }
  231.                   goal '.'                              {}
  232.                 | sections                              {}
  233.                 ;
  234. goal            : DO                                    { check_agent(kind);
  235.                                                           type = Top;
  236.                                                           flow = OUT;
  237.                                                           vars = NUL;
  238.                                                           step = BODY; }
  239.                   body                                  { goal = Goal_(atts0, vars, $3); }
  240.                 ;
  241. sections        : sections section                      {}
  242.                 | section                               {}
  243.                 ;
  244. section         : '#' INTEGER STRING                    { lineno = $2;
  245.                                                           fname  = $3; }
  246.                 | specification                         {}
  247.                 | implementation                        {}
  248.                 ;
  249. specification   : header                                { aoff  = aoff > 0 ? aoff : goff;
  250.                                                           atts0 = NUL;
  251.                                                           self  = Self; }
  252.                   '{' declarations0 '}'                 { specs = Spec_($1, Soff(specs), level, aoff, base,
  253.                                                                         genes, conds, csts, atts, mets, specs); }
  254.                 ;
  255. header          : CLASS isa0 cid conditions0            { $$ = $3; }
  256.                 | CID   isa  cid conditions0            { $$ = $3; }
  257.                 | CLASS isa0 id  generics0              { $$ = $3; }
  258.                 | ID    isa  id  generics0              { $$ = $3; }
  259.                 ;
  260. isa             : ISA                                   { search_spec($<s>0, specs, &level, &aoff, &base,
  261.                                                                       &gs, &conds, &csts, &atts, &mets);
  262.                                                           level++; }
  263.                 ;
  264. isa0            : empty                                 { level = 0;
  265.                                                           aoff  = 0;
  266.                                                           base  = NUL;
  267.                                                           gs    = NUL;
  268.                                                           conds = NUL;
  269.                                                           csts  = NUL;
  270.                                                           atts  = NUL;
  271.                                                           mets  = NUL; }
  272.                 ;
  273. cid             : CID                                   { $$ = $1; goff = 4; }
  274.                 ;
  275. id              : ID                                    { $$ = $1; goff = 1; }
  276.                 ;
  277. generics0       :                                       { clash_spec($<s>0, specs);
  278.                                                           genes = NUL;
  279.                                                           prot  = PROTECTED; }
  280.                   genes0                                { count_genes(gs); }
  281.                 ;
  282. genes0          : LT genes GT                           {}
  283.                 | empty                                 {}
  284.                 ;
  285. genes           : genes ',' gene                        { $$ = $1->next = $3; }
  286.                 | gene                                  { $$ = genes = $1; }
  287.                 ;
  288. gene            : SID                                   { clash_gene($1, genes);
  289.                                                           check_gene(gs, level, $1);
  290.                                                           count_gene(gs, level, $1);
  291.                                                           gs = gs ? gs->next : NUL;
  292.                                                           $$ = Gene_($1, goff++, NUL); }
  293.                 ;
  294. conditions0     : '[' conditions ']'                    {}
  295.                 | empty                                 {}
  296.                 ;
  297. conditions      : conditions ',' condition              {}
  298.                 | condition                             {}
  299.                 | error                                 {}
  300.                 ;
  301. condition       : SID                                   { clash_cond($1, conds);
  302.                                                           conds = Cond_($1, Coff(conds), conds); }
  303.                 ;
  304. declarations0   : constants  attributes methods         {}
  305.                 | constants  attributes                 {}
  306.                 | constants  methods                    {}
  307.                 | attributes methods                    {}
  308.                 | constants                             {}
  309.                 | attributes                            {}
  310.                 | methods                               {}
  311.                 | empty                                 {}
  312.                 ;
  313. constants       : constants    constant                 {}
  314.                 | CONSTANT ':' constant                 {}
  315.                 ;
  316. constant        : type                                  { type = $1; }
  317.                   consts ';'                            {}
  318.                 | error ';'                             {}
  319.                 ;
  320. consts          : consts ',' const                      {}
  321.                 | const                                 {}
  322.                 ;
  323. const           : attid '=' expr                        { check_ref($3.node, BODY, IN, type);
  324.                                                           csts = Cst_($1, $3.node, csts); }
  325.                 ;
  326. attributes      : attributes    attribute               {}
  327.                 | ATTRIBUTE ':' attribute               {}
  328.                 ;
  329. attribute       : protection type                       { type = $2; }
  330.                   atts ';'                              {}
  331.                 | error ';'                             {}
  332.                 ;
  333. atts            : atts ',' att                          {}
  334.                 | att                                   {}
  335.                 ;
  336. att             : attid '='                             { vars = NUL;
  337.                                                           step = BODY;
  338.                                                           flow = IN; }
  339.                   rvalue                                { atts = Att_($1, aoff++, level, prot, type, $4, atts); }
  340.                 | attid                                 { atts = Att_($1, aoff++, level, prot, type, null(type), atts); }
  341.                 ;
  342. attid           : ID                                    { clash_cst($1, csts);
  343.                                                           clash_att($1, level, atts);
  344.                                                           $$ = $1; }
  345.                 ;
  346. methods         : methods    method                     {}
  347.                 | METHOD ':' method                     {}
  348.                 ;
  349. method          : protection ID                         { clash_met($2, level, mets);
  350.                                                           args0 = args = NUL; }
  351.                   '(' arguments0 ')' '.'                { mets = Met_($2, Moff(mets), level, prot, args0, mets); }
  352.                 | error ';'                             {}
  353.                 ;
  354. arguments0      : arguments                             {}
  355.                 | empty                                 {}
  356.                 ;
  357. arguments       : arguments ';' argument                { $1->next = args;
  358.                                                           $$ = $3; }
  359.                 | argument                              { args0 = args;
  360.                                                           $$ = $1; }
  361.                 ;
  362. argument        : type                                  { type = $1; }
  363.                   args                                  { $$ = $3; }
  364.                 ;
  365. args            : args ',' arg                          { $$ = $1->next = $3; }
  366.                 | arg                                   { $$ = args = $1; }
  367.                 ;
  368. arg             :     argid                             { $$ = Arg_($1, IN,  type, NUL); }
  369.                 | '?' argid                             { $$ = Arg_($2, OUT, type, NUL); }
  370.                 ;
  371. argid           : CID                                   { clash_arg($1, args);
  372.                                                           clash_arg($1, args0);
  373.                                                           $$ = $1; }
  374.                 ;
  375. protection      : PUBLIC                                { prot = PUBLIC; }
  376.                 | PROTECTED                             { prot = PROTECTED; }
  377.                 | PRIVATE                               { prot = PRIVATE; }
  378.                 | empty                                 {}
  379.                 ;
  380. types0          : LT types GT                           { $$ = $2; }
  381.                 | empty                                 { $$ = NUL; }
  382.                 ;
  383. types           : type ',' types                        { $$ = Con_($1, $3); }
  384.                 | type                                  { $$ = Con_($1, NUL); }
  385.                 ;
  386. type            : SID                                   { search_gene($1, genes, &goff);
  387.                                                           $$ = Type_(META,   goff); }
  388.                 | type '*'                              { $$ = Type_(LIST,   $1); }
  389.                 | type '[' dimensions ']'               { $$ = Type_(ARRAY,  Array_($1, $3)); }
  390.                 | ID types0                             { $$ = Type_(OBJECT, Class_($1, $2)); }
  391.                 | CID                                   { $$ = Type_(AGENT,  Class_($1, NUL)); }
  392.                 | INT                                   { $$ = Int; }
  393.                 | REAL                                  { $$ = Real; }
  394.                 | CHAR                                  { $$ = Char; }
  395.                 ;
  396. dimensions      : dimension ',' dimensions              { $$ = Dim_($1, $3); }
  397.                 | dimension                             { $$ = Dim_($1, NUL); }
  398.                 ;
  399. dimension       : expr                                  { check_dim($1.node);
  400.                                                           $$ = $1.node->this.i; }
  401.                 | '_'                                   { $$ = 0; }
  402.                 ;
  403. implementation  : identifier                            { search_spec($1, specs, &level, &_, &base,
  404.                                                                       &genes, &conds, &csts, &atts0, &mets);
  405.                                                           clash_imp($1, imps);
  406.                                                           t     = Type_(kind, Class_($1, make_cons(genes)));
  407.                                                           self  = Node_p(SELF, t, NUL, NUL);
  408.                                                           goal  = NUL;
  409.                                                           rules = NUL; }
  410.                   '{' definitions0 '}'                  { imps  = Imp_($1, base, goal, rules, imps); }
  411.                 ;
  412. identifier      : CID                                   { $$ = $1; kind = AGENT;  }
  413.                 | ID                                    { $$ = $1; kind = OBJECT; }
  414.                 ;
  415. definitions0    : goal  '.' rules '.'                   {}
  416.                 | goal  '.'                             {}
  417.                 | rules '.'                             {}
  418.                 | empty                                 {}
  419.                 ;
  420. rules           : rules '.' rule                        { $$ = $1 ? ($1->next = $3) : (rules = $3); }
  421.                 | rule                                  { $$ = rules = $1; }
  422.                 | error                                 { $$ = NUL; }
  423.                 ;
  424. rule            : clause                                { check_vars(vars);
  425.                                                           $$ = $1; }
  426.                 ;
  427. clause          : head IF body THEN body                { $$ = Rule_(vars, $1,  $3,  $5, last, NUL); }
  428.                 | head IF body                          { $$ = Rule_(vars, $1,  $3, NUL, last, NUL); }
  429.                 | head THEN body                        { $$ = Rule_(vars, $1, NUL,  $3, last, NUL); }
  430.                 | head                                  { $$ = Rule_(vars, $1, NUL, NUL, last, NUL); }
  431.                 ;
  432. head            : ID                                    { search_met($1, level, PROTECTED, mets, &moff, &prot, &args);
  433.                                                           clash_head($1, rules, rules ? $<rule>-1 : NUL);
  434.                                                           vars = NUL;
  435.                                                           step = HEAD; }
  436.                   '(' parameters0 _l4                   { update_vars(vars);
  437.                                                           step = BODY;
  438.                                                           last = NUL;
  439.                                                           $$ = Head_($1, moff, prot, $4); }
  440.                 ;
  441. body            : cluster ';' body                      { $$ = Clu_($1, step, $3); }
  442.                 | cluster                               { $$ = Clu_($1, step, NUL); }
  443.                 ;
  444. cluster         : messages                              { update_vars(vars);
  445.                                                           step += NEXT;
  446.                                                           type  = Top;
  447.                                                           flow  = OUT;
  448.                                                           $$ = $1; }
  449.                 ;
  450. messages        : message                               { check_remote($1->tag);
  451.                                                           undo_vars(vars); }
  452.                   ',' messages                          { $1->next = $4;
  453.                                                           $$ = $1; last = NUL; }
  454.                 | message                               { $$ = $1; last = NUL; }
  455.                 | predicate                             { $$ = $1; last = $1;  }
  456.                 | primitive                             { $$ = $1; last = NUL; }
  457.                 ;
  458. message         : destination                           { char *name = ref_class($1->type);
  459.                                                           search_spec(name, specs, &$<i>$, &size, &_,
  460.                                                                       &gs, &_, &_, &_, &ms);
  461.                                                           if ($1->tag == HANDLE) $1->this.i = size; }
  462.                   '!' ID                                { search_met($4, ($<i>2)+1, PUBLIC, ms, &moff, &_, &args);
  463.                                                           args = subs_args(args, gs, get_cons($1->type)); }
  464.                   '(' parameters0 _l4                   { $$ = Pred_($1->type->tag == AGENT  ? SEND
  465.                                                                    : $1->type->tag == OBJECT ? INVK
  466.                                                                    : same($4, "wait") ? WAIT : POST,
  467.                                                                      moff, $7, $1, NUL); }
  468.                 ;
  469. predicate       : identifier                            { search_base($1, base, &$<i>$, &ms); }
  470.                   ISA ID                                { search_met($4, $<i>2, PROTECTED, ms, &moff, &_, &args); }
  471.                   '(' parameters0 _l4                   { $$ = Pred_(CALL, moff, $7, $1, NUL); }
  472.                 | ID                                    { search_met($1, level, PROTECTED, mets, &moff, &_, &args); }
  473.                   '(' parameters0 _l4                   { $$ = Pred_(CALL, moff, $4, NUL, NUL); }
  474.                 ;
  475. destination     : handle                                { $$ = $1; }
  476.                 | global                                { $$ = $1; }
  477.                 | local                                 { $$ = $1; }
  478.                 | self                                  { $$ = $1; }
  479.                 | SID                                   { search_cond($1, conds, &coff);
  480.                                                           $$ = Node_i(COND, Condv, coff, NUL); }
  481.                 ;
  482. _l4             :                                       { count_pars(args); }
  483.                   ')'                                   { type = Top;
  484.                                                           flow = OUT; }
  485.                 ;
  486. primitive       : matching                              { $$ = $1; }
  487.                 | comparison                            { $$ = $1; }
  488.                 ;
  489. matching        : '(' type ')'                          { type = $2;
  490.                                                           flow = OUT; }
  491.                   value '='                             { flow = IN; }
  492.                   rvalue                                { $$ = Pred_(RELOP, IS, $8, $5, NUL); }
  493.                 | gvalue '='                            { type = $1->type;
  494.                                                           flow = IN; }
  495.                   rvalue                                { $$ = Pred_(RELOP, IS, $4, $1, NUL); }
  496.                 ;
  497. comparison      : lhs relop rhs                         { $$ = eval_relop($1, $2, $3); }
  498.                 ;
  499. rhs             : expression2                           { $$ = $1; }
  500.                 | lhs                                   { $$ = $1; }
  501.                 ;
  502. lhs             : global                                { $$ = $1; }
  503.                 | local                                 { $$ = $1; }
  504.                 | literal                               { $$ = $1; }
  505.                 | self                                  { $$ = $1; }
  506.                 | nil                                   { $$ = $1; }
  507.                 | null                                  { $$ = $1; }
  508.                 ;
  509. relop           : EQ                                    { $$ = EQ; }
  510.                 | NE                                    { $$ = NE; }
  511.                 | LT                                    { $$ = LT; }
  512.                 | LE                                    { $$ = LE; }
  513.                 | GT                                    { $$ = GT; }
  514.                 | GE                                    { $$ = GE; }
  515.                 ;
  516. parameters0     : parameters                            { $$ = $1; }
  517.                 | empty                                 { $$ = NUL; }
  518.                 ;
  519. parameters      : parameter ',' parameters              { $1->next = $3;
  520.                                                           $$ = $1; }
  521.                 | parameter                             { $$ = $1; }
  522.                 ;
  523. parameter       :                                       { count_par(args);
  524.                                                           type = args ? args->type : Top;
  525.                                                           flow = args ? args->flow : NUL; }
  526.                   value                                 { args = args ? args->next : NUL;
  527.                                                           $$ = Par_(flow, $2, NUL); }
  528.                 ;
  529. value           : lvalue                                { $$ = $1; }
  530.                 | rvalue                                { $$ = $1; }
  531.                 | '_'                                   { $$ = isin(step, flow) ? null(type) : Anon; }
  532.                 ;
  533. pvalue          : lvalue                                { $$ = $1; }
  534.                 | rvalue                                { $$ = $1; }
  535.                 | '_'                                   { $$ = isin(step, flow) ? atts->init : Anon; }
  536.                 ;
  537. lvalue          : varid  prime ':' value                { $$ = Node_p(AS, $4->type, $4, $1);
  538.                                                           check_lvar($1, step, flow, $4->type); }
  539.                 | varid  prime                          { check_lvar($1, step, flow, type); $$ = $1; }
  540.                 | gvalue                                { check_lref($1, step, flow, type); $$ = $1; }
  541.                 ;
  542. gvalue          : global prime ':' value                { $$ = Node_p(AS, $1->type, $4, $1); }
  543.                 | global prime                          { $$ = $1; }
  544.                 ;
  545. rvalue          : expression2                           { check_ref($1, step, flow, type); $$ = $1; }
  546.                 | global                                { check_ref($1, step, flow, type); $$ = $1; }
  547.                 | varid                                 { check_var($1, step, flow, type); $$ = $1; }
  548.                 | literal                               { check_ref($1, step, flow, type); $$ = $1; }
  549.                 | self                                  { check_ref($1, step, flow, type); $$ = $1; }
  550.                 | nil                                   { check_nil(type); $$ = $1; }
  551.                 | instance                              { $$ = $1; }
  552.                 ;
  553. instance        : list                                  { $$ = $1; if (isout(step, flow)) flip($1->tag); }
  554.                 | array                                 { $$ = $1; }
  555.                 | string                                { $$ = $1; }
  556.                 | handle                                { $$ = $1; }
  557.                 | agent                                 { $$ = $1; }
  558.                 | object                                { $$ = $1; }
  559.                 ;
  560. list            : l2 elements '|'                       { type = $1; }
  561.                   value ']'                             { $$ = Node_p(LIST, type = $1, $2,  $5);  }
  562.                 | l2 elements ']'                       { $$ = Node_p(LIST, type = $1, $2,  NUL); }
  563.                 | l2 ']'                                { $$ = Node_p(LIST, type = $1, NUL, NUL); }
  564.                 ;
  565. null            : '[' ']'                               { $$ = Node_p(LIST, type, NUL, NUL); }
  566.                 ;
  567. l2              : '['                                   { $$ = type;  type = get_elem(type); }
  568.                 ;
  569. elements        : element ',' elements                  { $$ = Prop_($1, $3); }
  570.                 | element                               { $$ = Prop_($1, NUL); }
  571.                 ;
  572. element         : value                                 { $$ = $1; }
  573.                 ;
  574. array           : l3 '[' sizes_l3 l5 items0 _l5         { $$ = Node_p(ARRAY, $3.type, $3.node, $5); }
  575.                 | l3 '[' sizes_l3                       { $$ = Node_p(ARRAY, $3.type, $3.node, NUL); }
  576.                 ;
  577. string          : STRING                                { t  = Type_(ARRAY, Array_(Char, Dim_(strlen($1), NUL)));
  578.                                                           $$ = Node_p(STRING, t, $1, NUL);
  579.                                                           check_string($1, t, type); }
  580.                 ;
  581. l3              : '$'                                   { $$.dims = dims;  dims = get_dims(type);
  582.                                                           $$.type = type;  type = Int; }
  583.                 ;
  584. sizes_l3        : sizes                                 { count_sizes(dims); }
  585.                   ']'                                   { dims = $<idx>-1.dims;
  586.                                                           type = $<idx>-1.type;
  587.                                                           $$.dims = $1.dims;
  588.                                                           $$.type = Type_(ARRAY, Array_(get_item(type), $1.dims));
  589.                                                           $$.node = Node_i(DOPE, $$.type, $1.size, $1.props);
  590.                                                           if (isout(step, flow)) flip($$.node->tag); }
  591.                 ;
  592. sizes           : size ',' sizes                        { $$.props = Prop_($1.node, $3.props);
  593.                                                           $$.dims  = Dim_($1.size,  $3.dims);
  594.                                                           $$.size  = $1.size * $3.size; }
  595.                 | size                                  { $$.props = Prop_($1.node, NUL);
  596.                                                           $$.dims  = Dim_($1.size,  NUL);
  597.                                                           $$.size  = $1.size; }
  598.                 ;
  599. size            :                                       { count_size(dims); }
  600.                   value                                 { check_size($2, step, flow, dims);
  601.                                                           $$.size = grab_size($2, dims);
  602.                                                           $$.node = $2;
  603.                                                           dims = dims ? dims->next : NUL; }
  604.                 ;
  605. l5              : '{'                                   { $$.dims = dims;  dims = $<ary>0.dims;
  606.                                                           $$.size = size;  size = dims->size;
  607.                                                           $$.type = type;  type = get_item(type); }
  608.                 ;
  609. _l5             :                                       { count_items(size); }
  610.                   '}'                                   { dims = $<ary>-1.dims;
  611.                                                           size = $<ary>-1.size;
  612.                                                           type = $<ary>-1.type; }
  613.                 ;
  614. items0          : empty items                           { $$ = $<node>1; }
  615.                 ;
  616. items           : items ',' item                        { $$ = $1->that = $3; }
  617.                 | item                                  { $$ = $<node>0 = $1; }
  618.                 ;
  619. item            :                                       { count_item(size--); }
  620.                   component                             { $$ = $2; }
  621.                 ;
  622. component       :                                       { count_dim(dims); }
  623.                   l6 items0 _l6                         { $$ = Node_i(ITEM, type, $3, NUL); }
  624.                 |                                       { count_dims(dims); }
  625.                   value                                 { $$ = Node_i(ITEM, type, $2, NUL); }
  626.                 ;
  627. l6              : '{'                                   { $$.dims = dims;  dims = dims ? dims->next : NUL;
  628.                                                           $$.size = size;  size = dims ? dims->size : -1; }
  629.                 ;
  630. _l6             :                                       { count_items(size); }
  631.                   '}'                                   { dims = $<ary>-1.dims;
  632.                                                           size = $<ary>-1.size; }
  633.                 ;
  634. handle          : CID                                   { t = Type_(AGENT, Class_($1, NUL));
  635.                                                           check_handle(t, type);
  636.                                                           search_spec($1, specs, &_, &$<i>$, &_,
  637.                                                                       &gs, &_, &_, &as, &_); }
  638.                   atsite                                { $$ = Node_i(HANDLE, t, $<i>2, $3); }
  639.                 ;
  640. atsite0         : atsite                                { $$ = $1; }
  641.                 | empty                                 { $$ = Site; }
  642.                 ;
  643. atsite          : ATINET ':' INTEGER                    { $$ = Node_p(SITE, Bot, $1, (Node *) $3); }
  644.                 | ATINET                                { $$ = Node_p(SITE, Bot, $1, (Node *)  0); }
  645.                 ;
  646. agent           : CID                                   { check_name($1, get_agent(type)); }
  647.                   l1 properties0 _l1 atsite0            { $$ = Node_p(AT, t, Node_p(AGENT, t, $3.size, $4), $6); }
  648.                 ;
  649. object          : ID                                    { check_name($1, get_object(type)); }
  650.                   l1 properties0 _l1                    { $$ = Node_p(OBJECT, t, $3.size, $4); }
  651.                 ;
  652. l1              :                                       { search_spec($<s>-1, specs, &_, &$$.size, &_,
  653.                                                                       &gs, &_, &_, &as, &_); }
  654.                   '{'                                   { $$.t    = Type_(type->tag, Class_($<s>-1, get_cons(type)));
  655.                                                           $$.atts = atts;  atts = subs_ratts(as, gs, get_cons(type));
  656.                                                           $$.type = type; }
  657.                 ;
  658. _l1             :                                       { count_props(atts); }
  659.                   '}'                                   { t    = $<inst>-1.t;
  660.                                                           atts = $<inst>-1.atts;
  661.                                                           type = $<inst>-1.type; }
  662.                 ;
  663. properties0     : empty properties                      { $$   = $<prop>1;
  664.                                                           atts = next_atts(atts, isin(step, flow), &$2->next, &_); }
  665.                 | empty                                 { atts = next_atts(atts, isin(step, flow), &$$, &_); }
  666.                 ;
  667. properties      : properties ',' property               { $1->next = $<prop>2;
  668.                                                           $$ = $3; }
  669.                 | property                              { $$ = $1; }
  670.                 ;
  671. property        :                                       { atts = next_atts(atts, isin(step, flow), &$<prop>0, &$<prop>$);
  672.                                                           type = atts ? atts->type : Top;
  673.                                                           count_prop(atts); }
  674.                   pvalue                                { $$ = Prop_($2, NUL);
  675.                                                           if (!$<prop>0) $<prop>0 = $$;
  676.                                                           else $<prop>1->next = $$;
  677.                                                           atts = atts ? atts->next : NUL; }
  678.                 ;
  679. prime           : '\''                                  { check_lvalue($<node>0->tag);
  680.                                                           flip($<node>0->tag); }
  681.                 ;
  682. global          : local accessors                       { $1->that = $2;
  683.                                                           $1->type = t;
  684.                                                           $$ = $1; }
  685.                 | refid accessors                       { $1->that = $2;
  686.                                                           $1->type = t;
  687.                                                           $$ = $1; }
  688.                 | refid                                 { $$ = $1; }
  689.                 ;
  690. local           : varid                                 { check_bound($1, step, flow);
  691.                                                           $$ = $1; }
  692.                 ;
  693. varid           : CID                                   { Var *var = find_var($1, vars);
  694.                                                           if (!var) var = vars =
  695.                                                           Var_($1, 0, FF, UNDEF, UNDEF, type, type, type, vars);
  696.                                                           $$ = Node_p(VAR, var->mint, var, NUL); }
  697.                 ;
  698. refid           : ID                                    { if (self == Self && xxchar == '\'') {
  699.                                                               aoff  = Aoff(atts0); t = type;
  700.                                                               atts0 = Att_($1, aoff, level, PROTECTED, t, null(t), atts0);
  701.                                                               $$ = Node_i(REF, type, aoff, NUL);
  702.                                                           }
  703.                                                           else {
  704.                                                               Cst *cst = find_cst($1, csts);
  705.                                                               if (!cst) search_att($1, level, PROTECTED, atts0, &aoff, &t);
  706.                                                               $$ = cst ? cst->node : Node_i(REF, t, aoff, NUL);
  707.                                                           }}
  708.                 ;
  709. accessors       : accessor accessors                    { $1->that = $2;
  710.                                                           $$ = $1; }
  711.                 | accessor                              { $$ = $1; }
  712.                 ;
  713. accessor        :                                       { char *name = ref_object($<node>0->type);
  714.                                                           search_spec(name, specs, &$<i>$, &_, &_,
  715.                                                                       &gs, &_, &_, &as, &_); }
  716.                   DOT ID                                { search_att($3, ($<i>1)+1, PUBLIC, as, &aoff, &t);
  717.                                                           t  = subs_type(t, gs, get_cons($<node>0->type));
  718.                                                           $$ = Node_i(FIELD, t, aoff, NUL); }
  719.                 | l0 indices _l0                        { t  = get_item($<node>0->type);
  720.                                                           $$ = Node_p(INDEX, t, $2, NUL); }
  721.                 ;
  722. l0              : '['                                   { $$ = dims;  dims = ref_dims($<node>0->type); }
  723.                 ;
  724. _l0             :                                       { count_indices(dims); }
  725.                   ']'                                   { dims = $<dim>-1; }
  726.                 ;
  727. indices         : index ',' indices                     { $$ = Prop_($1, $3); }
  728.                 | index                                 { $$ = Prop_($1, NUL); }
  729.                 ;
  730. index           :                                       { count_index(dims); }
  731.                   expression                            { check_index($2, dims);
  732.                                                           dims = dims ? dims->next : NUL;
  733.                                                           $$ = $2; }
  734.                 ;
  735. expression      : expr                                  { $$ = Node_p(EXPR, $1.node->type, $1.node, NUL); }
  736.                 ;
  737. expression2     : expr2                                 { $$ = Node_p(EXPR, $1.node->type, $1.node, NUL); }
  738.                 ;
  739. expr            : expr2                                 { $$.node = $1.node;
  740.                                                           $$.cost = $1.cost; }
  741.                 | expr1                                 { $$.node = $1.node;
  742.                                                           $$.cost = $1.cost; }
  743.                 ;
  744. term            : term2                                 { $$.node = $1.node;
  745.                                                           $$.cost = $1.cost; }
  746.                 | term1                                 { $$.node = $1.node;
  747.                                                           $$.cost = $1.cost; }
  748.                 ;
  749. factor          : factor2                               { $$.node = $1.node;
  750.                                                           $$.cost = $1.cost; }
  751.                 | factor1                               { $$.node = $1.node;
  752.                                                           $$.cost = $1.cost; }
  753.                 ;
  754. expr2           : expr addop term                       { $$.node = eval_arop($1.node, $2, $3.node);
  755.                                                           $$.cost = eval_cost($1.cost, $$.node, $3.cost); }
  756.                 | term2                                 { $$.node = $1.node;
  757.                                                           $$.cost = $1.cost;  }
  758.                 ;
  759. term2           : term mulop factor                     { $$.node = eval_arop($1.node, $2, $3.node);
  760.                                                           $$.cost = eval_cost($1.cost, $$.node, $3.cost); }
  761.                 | factor2                               { $$.node = $1.node;
  762.                                                           $$.cost = $1.cost; }
  763.                 ;
  764. factor2         : ID '(' expr ')'                       { $$.node = eval_fun($1, $3.node);
  765.                                                           $$.cost = $3.cost; }
  766.                 | '-' factor                            { $$.node = eval_uminus($2.node);
  767.                                                           $$.cost = $2.cost; }
  768.                 | '(' expr ')'                          { $$.node = $2.node;
  769.                                                           $$.cost = $2.cost;  }
  770.                 ;
  771. expr1           : term1                                 { $$.node = $1.node;
  772.                                                           $$.cost = $1.cost; }
  773.                 ;
  774. term1           : factor1                               { $$.node = $1.node;
  775.                                                           $$.cost = $1.cost; }
  776.                 ;
  777. factor1         : local                                 { check_num($1); $$.node = $1; $$.cost = 1; }
  778.                 | global                                { check_num($1); $$.node = $1; $$.cost = 1; }
  779.                 | INTEGER                               { $$.node = Node_i(INT,  Int,  $1, NUL); $$.cost = 0; }
  780.                 | FLOAT                                 { $$.node = Node_f(REAL, Real, $1, NUL); $$.cost = 0; }
  781.                 ;
  782. addop           : '+'                                   { $$ = ADD; }
  783.                 | '-'                                   { $$ = SUB; }
  784.                 ;
  785. mulop           : '*'                                   { $$ = MUL; }
  786.                 | '/'                                   { $$ = DIV; }
  787.                 | '%'                                   { $$ = REM; }
  788.                 ;
  789. literal         : INTEGER                               { $$ = Node_i(INT,  Int,  $1, NUL); }
  790.                 | FLOAT                                 { $$ = Node_f(REAL, Real, $1, NUL); }
  791.                 | CHARACTER                             { $$ = Node_p(CHAR, Char, $1, NUL); }
  792.                 ;
  793. self            : SELF                                  { check_self(self);
  794.                                                           $$ = self; }
  795.                 ;
  796. nil             : NIL                                   { $$ = Node_p(NIL, type, NUL, NUL); }
  797.                 ;
  798. empty           :                                       {}
  799.                 ;
  800. %%
  801. void    init_par()
  802. {
  803.         Top    = Type_(TOP,  Class_("$top",  NUL));
  804.         Bot    = Type_(BOT,  Class_("$bot",  NUL));
  805.         Int    = Type_(INT,  Class_("int",   NUL));
  806.         Real   = Type_(REAL, Class_("real",  NUL));
  807.         Char   = Type_(CHAR, Class_("char",  NUL));
  808.         Condv  = Type_(COND, Class_("$cond", NUL));
  809.  
  810.         Izero  = Node_i(INT,  Int,  0,   NUL);
  811.         Rzero  = Node_f(REAL, Real, (float) 0.0, NUL);
  812.         Blank  = Node_p(CHAR, Char, " ", NUL);
  813.         Nil    = Node_p(NIL,  Bot,  NUL, NUL);
  814.  
  815.         Anon   = Node_p(ANON, Bot,  NUL, NUL);
  816.         Self   = Node_p(SELF, Bot,  NUL, NUL);
  817.         Site   = Node_i(SITE, Bot,  "0",   0);
  818.  
  819.         specs  = Spec_("$cond", 1, 0, 0, NUL, NUL, NUL, NUL, NUL,
  820.                  Met_("post", 1, 0, PUBLIC, Arg_("", IN, Int, NUL),
  821.                  Met_("wait", 0, 0, PUBLIC, Arg_("", IN, Int, NUL), NUL)), NUL);
  822.         imps   = NUL;
  823.         Atts0  = NUL;
  824. }
  825.  
  826. void    parse(buf, linesz)
  827. char   *buf;
  828. int     linesz;
  829. {
  830.         init_lex(buf, linesz);
  831.         xxparse();
  832. }
  833.  
  834.